package cn.ilovese.collect.serviceimpl.task;

import cn.ilovese.collect.datamapper.device.DeviceMapper;
import cn.ilovese.collect.datamapper.device.DeviceRequirementMapper;
import cn.ilovese.collect.datamapper.file.FileMapper;
import cn.ilovese.collect.datamapper.task.TaskMapper;
import cn.ilovese.collect.datamapper.transaction.TransactionMapper;
import cn.ilovese.collect.datamapper.user.UserMapper;
import cn.ilovese.collect.datamapper.work.WorkMapper;
import cn.ilovese.collect.dto.recommend.WorkerGroupRecommend;
import cn.ilovese.collect.po.device.Device;
import cn.ilovese.collect.po.device.DeviceRequirement;
import cn.ilovese.collect.po.task.Task;
import cn.ilovese.collect.po.transaction.Transaction;
import cn.ilovese.collect.po.user.User;
import cn.ilovese.collect.po.work.Work;
import cn.ilovese.collect.service.task.TaskService;
import cn.ilovese.collect.util.Constant;
import cn.ilovese.collect.vo.Device.DeviceRequirementVO;
import cn.ilovese.collect.vo.Device.DeviceVO;
import cn.ilovese.collect.vo.NullVO;
import cn.ilovese.collect.vo.ResultVO;
import cn.ilovese.collect.vo.task.TaskFormVO;
import cn.ilovese.collect.vo.task.TaskVO;
import cn.ilovese.collect.vo.task.TaskWithUsernameVO;
import cn.ilovese.collect.vo.user.UserVO;
import cn.ilovese.collect.vo.user.WorkerInfoVO;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@CacheConfig(cacheNames = "task",cacheManager = "cacheManager")
public class TaskServiceImpl implements TaskService {
    // @Resource标识特定的目标组件，你们自己添加，类似软工二
    // @Autowired装载java bean，用于set方法，你们自己添加，类似软工二
    //注意在这里添加每个实现方法的说明注释，类似以下
    /**
     * 这个方法干了什么
     *
     * @param 参数1 解释
     * @param 参数2 解释
     * ......
     * @return 返回值解释
     */

    @Resource
    TaskMapper taskMapper;
    @Resource
    UserMapper userMapper;
    @Resource
    FileMapper fileMapper;
    @Resource
    WorkMapper workMapper;
    @Resource
    DeviceRequirementMapper deviceRequirementMapper;
    @Resource
    DeviceMapper deviceMapper;
    @Resource
    TransactionMapper transactionMapper;

    @Override
    public ResultVO<List<TaskWithUsernameVO>> getAllTasks() {
        List<Task> temp = taskMapper.selectAll();
        if(temp.size() == 0)
            return new ResultVO<>(Constant.REQUEST_FAIL,"获取任务列表失败");
        List<TaskWithUsernameVO> res = new ArrayList<>();
        for(Task task: temp){
            int uid = task.getUserId();
            if(uid==4)
                continue;
            String username = userMapper.selectByPrimaryKey(uid).getUsername();
            TaskWithUsernameVO taskTemp=new TaskWithUsernameVO(task,username);
            if(!taskTemp.getType().equals("collaboration_test")) {
                taskTemp.setDeviceRequirement(new DeviceRequirementVO(deviceRequirementMapper.selectByTask(task.getId())));
            }
            res.add(taskTemp);
        }
        return new ResultVO<>(Constant.REQUEST_SUCCESS,"获取任务列表成功",res);
    }

    @Override
    public ResultVO<List<TaskWithUsernameVO>> getAllValidTasks(Integer userId){
        Date curr = new Date();
        List<Task> temp = taskMapper.selectValidTasks(new Timestamp(curr.getTime()));
        if(temp.size() == 0)
            return new ResultVO<>(Constant.REQUEST_FAIL,"获取任务列表失败");
        List<TaskWithUsernameVO> res = new ArrayList<>();
        for(Task task: temp){
            int uid = task.getUserId();
            if(uid==4)
                continue;
            String username = userMapper.selectByPrimaryKey(uid).getUsername();
            TaskWithUsernameVO taskTemp=new TaskWithUsernameVO(task,username);
            if(!taskTemp.getType().equals("collaboration_test")) {
                taskTemp.setDeviceRequirement(new DeviceRequirementVO(deviceRequirementMapper.selectByTask(task.getId())));
                List<Device> userDeviceList = deviceMapper.selectByUserId(userId);
                boolean capableToClaim = false;
                if (userDeviceList != null) {
                    for (Device device : userDeviceList) {
                        if (device.getRam() >= taskTemp.getDeviceRequirement().getMinRam()
                                && device.getRam() >= taskTemp.getDeviceRequirement().getMaxRam()
                                && taskTemp.getDeviceRequirement().getOsList().contains(device.getOs())
                                && taskTemp.getDeviceRequirement().getProcessorArchitectureList().contains(device.getProcessorArchitecture())
                        ) {
                            capableToClaim = true;
                            break;
                        }
                    }
                }
                taskTemp.setCapableToClaim(capableToClaim);
            }
            res.add(taskTemp);
        }
        return new ResultVO<>(Constant.REQUEST_SUCCESS,"获取任务列表成功",res);
    }

    @Override
    public List<TaskVO> getTasksNeedWorker() {
        List<Task> temp = taskMapper.selectTaskNeedsWorker();
        if(temp == null)
            return null;
        List<TaskVO> res = new ArrayList<>();
        for(Task task: temp){
            if(task.getUserId()==4)
                continue;
            res.add(new TaskVO(task));
        }
        return res;
    }

    @Override
    public ResultVO<List<TaskWithUsernameVO>> getProducedTasks(Integer uid) {
        List<Task> temp = taskMapper.selectProducedTask(uid, new Timestamp(new Date().getTime()));
        if(temp.size() == 0)
            return new ResultVO<>(Constant.REQUEST_FAIL, "获取任务列表失败");
        List<TaskWithUsernameVO> res = new ArrayList<>();
        for(Task task: temp){
            if(task.getUserId()==4)
                continue;
            String bossname = userMapper.selectByPrimaryKey(task.getUserId()).getUsername();
            TaskWithUsernameVO taskTemp=new TaskWithUsernameVO(task,bossname);
            if(!taskTemp.getType().equals("collaboration_test")) {
                taskTemp.setDeviceRequirement(new DeviceRequirementVO(deviceRequirementMapper.selectByTask(task.getId())));
                List<Device> userDeviceList = deviceMapper.selectByUserId(uid);
                boolean capableToClaim = false;
                if (userDeviceList != null) {
                    for (Device device : userDeviceList) {
                        if (device.getRam() >= taskTemp.getDeviceRequirement().getMinRam()
                                && device.getRam() >= taskTemp.getDeviceRequirement().getMaxRam()
                                && taskTemp.getDeviceRequirement().getOsList().contains(device.getOs())
                                && taskTemp.getDeviceRequirement().getProcessorArchitectureList().contains(device.getProcessorArchitecture())
                        ) {
                            capableToClaim = true;
                            break;
                        }
                    }
                }

                taskTemp.setCapableToClaim(capableToClaim);
            }
            res.add(taskTemp);
        }
        return new ResultVO<>(Constant.REQUEST_SUCCESS,"获取任务列表成功",res);
    }

    @Override
    public ResultVO<List<TaskWithUsernameVO>> getCompletedTasks(Integer uid) {
        String bossname =  userMapper.selectByPrimaryKey(uid).getUsername();
        List<Task> temp = taskMapper.selectCompletedTask(uid, new Timestamp(new Date().getTime()));
        if(temp.size() == 0)
            return new ResultVO<>(Constant.REQUEST_FAIL, "获取任务列表失败");
        List<TaskWithUsernameVO> res = new ArrayList<>();
        for(Task task: temp){
            if(task.getUserId()==4)
                continue;
            TaskWithUsernameVO taskTemp=new TaskWithUsernameVO(task,bossname);
            if(!taskTemp.getType().equals("collaboration_test")) {
                taskTemp.setDeviceRequirement(new DeviceRequirementVO(deviceRequirementMapper.selectByTask(task.getId())));
                List<Device> userDeviceList = deviceMapper.selectByUserId(uid);
                boolean capableToClaim = false;
                if (userDeviceList != null) {
                    for (Device device : userDeviceList) {
                        if (device.getRam() >= taskTemp.getDeviceRequirement().getMinRam()
                                && device.getRam() >= taskTemp.getDeviceRequirement().getMaxRam()
                                && taskTemp.getDeviceRequirement().getOsList().contains(device.getOs())
                                && taskTemp.getDeviceRequirement().getProcessorArchitectureList().contains(device.getProcessorArchitecture())
                        ) {
                            capableToClaim = true;
                            break;
                        }
                    }
                }
                taskTemp.setCapableToClaim(capableToClaim);
            }
            res.add(taskTemp);
        }
        return new ResultVO<>(Constant.REQUEST_SUCCESS,"获取任务列表成功",res);
    }

    @Override
    public ResultVO<List<TaskWithUsernameVO>> getWorkingTasks(Integer uid) {
        List<Task> temp = taskMapper.selectWorkingTask(uid);
        if(temp.size() == 0)
            return new ResultVO<>(Constant.REQUEST_FAIL, "获取任务列表失败");
        List<TaskWithUsernameVO> res = new ArrayList<>();
        for(Task task: temp){
            if(task.getUserId()==4)
                continue;
            String bossname = userMapper.selectByPrimaryKey(task.getUserId()).getUsername();
            TaskWithUsernameVO taskTemp=new TaskWithUsernameVO(task,bossname);
            if(!taskTemp.getType().equals("collaboration_test")) {
                taskTemp.setDeviceRequirement(new DeviceRequirementVO(deviceRequirementMapper.selectByTask(task.getId())));
                List<Device> userDeviceList = deviceMapper.selectByUserId(uid);
                boolean capableToClaim = false;
                if (userDeviceList != null) {
                    for (Device device : userDeviceList) {
                        if (device.getRam() >= taskTemp.getDeviceRequirement().getMinRam()
                                && device.getRam() >= taskTemp.getDeviceRequirement().getMaxRam()
                                && taskTemp.getDeviceRequirement().getOsList().contains(device.getOs())
                                && taskTemp.getDeviceRequirement().getProcessorArchitectureList().contains(device.getProcessorArchitecture())
                        ) {
                            capableToClaim = true;
                            break;
                        }
                    }
                }
                taskTemp.setCapableToClaim(capableToClaim);
            }
            res.add(taskTemp);
        }
        return new ResultVO<>(Constant.REQUEST_SUCCESS,"获取任务列表成功",res);
    }

    @Override
    public ResultVO<List<TaskWithUsernameVO>> getFinishedTasks(Integer uid) {
        List<Task> temp = taskMapper.selectFinishedTask(uid);
        if(temp.size() == 0)
            return new ResultVO<>(Constant.REQUEST_FAIL, "获取任务列表失败");
        List<TaskWithUsernameVO> res = new ArrayList<>();
        for(Task task: temp){
            if(task.getUserId()==4)
                continue;
            String bossname = userMapper.selectByPrimaryKey(task.getUserId()).getUsername();
            TaskWithUsernameVO taskTemp=new TaskWithUsernameVO(task,bossname);
            if(!taskTemp.getType().equals("collaboration_test")) {
                taskTemp.setDeviceRequirement(new DeviceRequirementVO(deviceRequirementMapper.selectByTask(task.getId())));
                List<Device> userDeviceList = deviceMapper.selectByUserId(uid);
                boolean capableToClaim = false;
                if (userDeviceList != null) {
                    for (Device device : userDeviceList) {
                        if (device.getRam() >= taskTemp.getDeviceRequirement().getMinRam()
                                && device.getRam() >= taskTemp.getDeviceRequirement().getMaxRam()
                                && taskTemp.getDeviceRequirement().getOsList().contains(device.getOs())
                                && taskTemp.getDeviceRequirement().getProcessorArchitectureList().contains(device.getProcessorArchitecture())
                        ) {
                            capableToClaim = true;
                            break;
                        }
                    }
                }
                taskTemp.setCapableToClaim(capableToClaim);
            }
            res.add(taskTemp);
        }
        return new ResultVO<>(Constant.REQUEST_SUCCESS,"获取任务列表成功",res);
    }

    @Override
    public ResultVO<TaskWithUsernameVO> getTaskById(Integer taskid) {
        Task task = taskMapper.selectByPrimaryKey(taskid);
        DeviceRequirement deviceRequirement=deviceRequirementMapper.selectByTask(taskid);
        if(task == null)
            return new ResultVO<>(Constant.REQUEST_FAIL,"获取详细信息失败");
        String username = userMapper.selectByPrimaryKey(task.getUserId()).getUsername();
        TaskWithUsernameVO res=new TaskWithUsernameVO(task,username);
        if(deviceRequirement!=null) {
            res.setDeviceRequirement(new DeviceRequirementVO(deviceRequirement));
        }
        else
            System.out.println("该任务暂无设备需求！");
        return new ResultVO<>(Constant.REQUEST_SUCCESS,"获取详细信息成功", res);
    }

    @Override
    public ResultVO<TaskVO> createTask(TaskFormVO task) {
        System.out.println(task.getReportPrice());
        int uid = userMapper.selectByUsername(task.getUsername()).getId();
        TaskVO taskVO = new TaskVO(task,uid);
        Task record = new Task(taskVO);
        record.setEnvironment("Android8");
        User bossWithBalance=userMapper.selectByPrimaryKey(uid);
        BigDecimal oldBalance = new BigDecimal(Double.toString(bossWithBalance.getBalance()));
        BigDecimal amount = new BigDecimal(Double.toString(task.getNeed_num()*task.getReportPrice()));
        bossWithBalance.setBalance(oldBalance.subtract(amount).doubleValue());
        if(bossWithBalance.getBalance()<0)
            return new ResultVO<>(Constant.REQUEST_FAIL,"发包方余额不足以发布任务");
        int updateRow=userMapper.updateByPrimaryKey(bossWithBalance);
        if (updateRow==1) {
            long timeNow = System.currentTimeMillis();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            Date nowTime=new Date();
            String nowDate = sdf.format(nowTime);
            String transactionNumber = "RT" + nowDate + timeNow;
            Transaction releaseTaskTransaction = new Transaction();
            releaseTaskTransaction.setTransactionNumber(transactionNumber);
            releaseTaskTransaction.setBalance(bossWithBalance.getBalance());
            releaseTaskTransaction.setIn(0);
            releaseTaskTransaction.setOut(task.getNeed_num()*task.getReportPrice());
            releaseTaskTransaction.setRemark("任务："+task.getTaskname());
            releaseTaskTransaction.setTime(nowTime);
            releaseTaskTransaction.setType("任务扣款");
            releaseTaskTransaction.setUserId(bossWithBalance.getId());
            int transId=transactionMapper.insert(releaseTaskTransaction);
            if(transId<=0){
                return new ResultVO<>(Constant.REQUEST_FAIL,"记录单号失败");
            }
        }
        int id = taskMapper.insert(record);
        if(task.getDeviceRequirement()!=null){
            DeviceRequirementVO newDeviceRequirement=task.getDeviceRequirement();
            newDeviceRequirement.setTaskId(record.getId());
            int device_id=deviceRequirementMapper.insert(
                    new DeviceRequirement(
                            newDeviceRequirement
                    )
            );
            if(device_id<1)
                System.out.println("插入任务的设备需求失败");
        }
        if(id < 1)
            return new ResultVO<>(Constant.REQUEST_FAIL, "插入失败");
        else{
            TaskVO res = new TaskVO(record);
            return new ResultVO<>(Constant.REQUEST_SUCCESS,"插入成功",res);
        }
    }

    @Override
    public ResultVO<TaskVO> updateTask(TaskVO task) {
        int id = task.getId();
        System.out.println(id);
        if(taskMapper.selectByPrimaryKey(id) == null)
            return new ResultVO<>(Constant.REQUEST_FAIL, "不存在此task");
        Task toBeUpdated = new Task(task);
        toBeUpdated.setId(id);
        int res = taskMapper.updateByPrimaryKey(toBeUpdated);
        if(res == 0)
            return new ResultVO<>(Constant.REQUEST_FAIL, "更新失败");
        return new ResultVO<>(Constant.REQUEST_SUCCESS,"更新成功",new TaskVO(toBeUpdated));

    }
    @Override
    public ResultVO<TaskVO> deleteTask(Integer taskid) {
        int id = taskMapper.deleteByPrimaryKey(taskid);
        System.out.println("id:" + id);
        if(id < 1)
            return new ResultVO<>(Constant.REQUEST_FAIL,"删除失败");
        return new ResultVO<>(Constant.REQUEST_SUCCESS, "删除成功");
    }

    @Override
    public ResultVO<List<WorkerInfoVO>> getWorkersOfTask(Integer taskid) {
        List<Work> workersIdList= workMapper.selectByTask(taskid);
        List<WorkerInfoVO> res=new ArrayList<>();
        for(Work work:workersIdList){
            WorkerInfoVO temp=new WorkerInfoVO(
                    userMapper.selectByPrimaryKey(work.getUserId())
            );
            res.add(temp);

        }
        return new ResultVO<>(Constant.REQUEST_SUCCESS, "获取该任务工人信息成功",res);
    }

    @Override
    public ResultVO<List<DeviceVO>> getDevicesToCompleteTask(Integer taskid, Integer userId) {
        DeviceRequirement deviceRequirementToCompleteTask=deviceRequirementMapper.selectByTask(taskid);
        List<Device> devicesUserHas=deviceMapper.selectByUserId(userId);
        List<DeviceVO> res=new ArrayList<>();
        for(Device device:devicesUserHas){
            if(deviceRequirementToCompleteTask.getProcessorArchitectureList().contains(device.getProcessorArchitecture())
            &&device.getRam()<=deviceRequirementToCompleteTask.getMaxRam()
                    &&device.getRam()>=deviceRequirementToCompleteTask.getMinRam()
                    &&deviceRequirementToCompleteTask.getOsList().contains(device.getOs())
            )
                res.add(new DeviceVO(device));
        }
        return new ResultVO<>(Constant.REQUEST_SUCCESS, "获取满足要求设备列表成功",res);
    }

    @Override
    public ResultVO<DeviceRequirementVO> getDeviceRequirements(Integer taskid) {
        DeviceRequirement deviceRequirementToCompleteTask=deviceRequirementMapper.selectByTask(taskid);
        if(deviceRequirementToCompleteTask!=null)
            return new ResultVO<>(Constant.REQUEST_SUCCESS, "获取任务的设备需求成功",new DeviceRequirementVO(deviceRequirementToCompleteTask));
        return new ResultVO<>(Constant.REQUEST_FAIL, "获取任务的设备需求失败");
    }


}
